package com.chhuang.system.controller;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.chhuang.core.bean.QueryBean;
import com.chhuang.core.validation.ValidGroupSave;
import com.chhuang.system.bean.ChMenuQueryBean;
import com.chhuang.system.consts.SysConstants;
import com.chhuang.system.po.ChMenu;
import com.chhuang.system.po.ChRole;
import com.chhuang.system.po.ChRoleMenuMap;
import com.chhuang.system.service.IChMenuService;
import com.chhuang.system.service.IChRoleMenuMapService;
import com.chhuang.system.service.IChRoleService;
import com.chhuang.utils.Assert;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

@Controller
@RequestMapping("/system/menu")
public class ChMenuController {
	private static final Log log = LogFactory.getLog(ChMenuController.class);
	
	@Autowired
	private IChMenuService chMenuService;
	@Autowired
	private IChRoleService chRoleService;
	@Autowired
	private IChRoleMenuMapService chRoleMenuMapService;
	
	/**
	 * 获取用户菜单
	 * @param request
	 * @return
	 * @throws Exception 
	 */
	@RequestMapping("/getMenu")
	@ResponseBody
	public Object getMenu(HttpServletRequest request) throws Exception{
		JSONArray array = new JSONArray();
		
		HttpSession session = request.getSession(false);
		String roleId = (String) session.getAttribute(SysConstants.ROLE_ID);
		
		if(Assert.isValidString(roleId)){
			List<ChRoleMenuMap> roleMenuMaps = chRoleMenuMapService.findByRoleId(roleId);
			if(Assert.isValidCollection(roleMenuMaps)){
				Map<String,ChMenu> firstMenus = new HashMap<String,ChMenu>();//一级菜单
				List<ChMenu> secondMenuList = new LinkedList<ChMenu>();//二级菜单
				for(ChRoleMenuMap roleMenuMap : roleMenuMaps){
					ChMenu menu = chMenuService.findByPrimaryKey(roleMenuMap.getMenuId());
					if(menu!=null){
						if(Assert.isValidString(menu.getParentId()) && !SysConstants.Symbol.NEGATIVE_ONE.equals(menu.getParentId())){
							ChMenu parentMenu = chMenuService.findByPrimaryKey(menu.getParentId());
							if(!firstMenus.containsKey(parentMenu.getMenuId())){
								firstMenus.put(parentMenu.getMenuId(), parentMenu);
							}
							secondMenuList.add(menu);
						}else{
							firstMenus.put(menu.getMenuId(), menu);
						}
					}
				}
				
				//一级菜单排序
				List<ChMenu> firstMenuList = new LinkedList<ChMenu>();
				for (Map.Entry<String, ChMenu> entry : firstMenus.entrySet()) {
					ChMenu menu = entry.getValue();
					if(firstMenuList.isEmpty() || firstMenuList.get(firstMenuList.size()-1).getMenuOrder()<=menu.getMenuOrder()){
						firstMenuList.add(entry.getValue());
					}else{
						int i=0;
						for(;i<firstMenuList.size();i++){
							if(firstMenuList.get(i).getMenuOrder()>menu.getMenuOrder()){
								break;
							}
						}
						firstMenuList.add(i, menu);
					}
					
				}
				
				for(ChMenu firstMenu : firstMenuList){
					JSONObject obj = new JSONObject();
					obj.put(SysConstants.MENU_NAME, firstMenu.getMenuName());
					obj.put(SysConstants.ICON, firstMenu.getIcon());
					if(firstMenu.getAsParent()){
						obj.put(SysConstants.AS_PARENT, firstMenu.getAsParent());
						JSONArray sons = new JSONArray();
						int i=0;
						for(;i<secondMenuList.size();i++){
							ChMenu secondMenu = secondMenuList.get(i);
							if(secondMenu.getParentId().equals(firstMenu.getMenuId())){
								JSONObject sonObj = new JSONObject();
								sonObj.put(SysConstants.MENU_NAME, secondMenu.getMenuName());
								sonObj.put(SysConstants.URL, secondMenu.getUrl());
								sons.add(sonObj);
								secondMenuList.remove(i--);
							}
						}
						obj.put(SysConstants.SONS, sons);
					}else{
						obj.put(SysConstants.URL, firstMenu.getUrl());
					}
					array.add(obj);
				}
				
			}
		}
		
		log.debug(array.toString());
		return array;
	}
	
	/**
	 * 根据菜单id获取菜单信息
	 * @param menuId
	 * @return
	 * @throws Exception 
	 */
	@RequestMapping(value="/findMenuById",method=RequestMethod.POST)
	@ResponseBody
	public Object findMenuById(String menuId) throws Exception{
		ChMenu menu = null;
		if(Assert.isValidString(menuId)){
			menu = chMenuService.findByPrimaryKey(menuId);
		}
		log.debug("根据菜单id获取菜单信息");
		return menu==null?SysConstants.Symbol.EMPTY_JSONOBJECT:menu;
	}
	
	/**
	 * 获取可弹出的菜单
	 * @param menuId
	 * @return
	 * @throws Exception 
	 */
	@RequestMapping(value="/findMenuAsParent",method=RequestMethod.GET)
	@ResponseBody
	public Object findMenuAsParent() throws Exception{
		List<ChMenu> menus = chMenuService.findAsParent();
		log.debug("获取可弹出的菜单");
		return Assert.isInvalidCollection(menus)?SysConstants.Symbol.EMPTY_JSONARRAY:menus;
	}
	
	/**
	 * 获取菜单列表
	 * @param menuQueryBean
	 * @return
	 * @throws Exception 
	 */
	@RequestMapping(value="/getList",method=RequestMethod.POST)
	@ResponseBody
	public Object getList(@RequestBody ChMenuQueryBean menuQueryBean) throws Exception{
		log.debug(menuQueryBean.getPageSize()+";"+menuQueryBean.getPageNum()
				+";"+menuQueryBean.getOrderBy()+";"+menuQueryBean.isDesc()
				+";"+menuQueryBean.isOr());
		
		QueryBean<ChMenu> queryBean = chMenuService.seniorQuery(menuQueryBean);
		
		return queryBean==null?SysConstants.Symbol.EMPTY_JSONOBJECT:queryBean;
	}
	
	/**
	 * 添加或修改菜单信息
	 * @param menu
	 * @return
	 * @throws Exception 
	 */
	@RequestMapping(value="/editMenu/{roleIds}",method=RequestMethod.POST)
	@ResponseBody
	public Object editMenu(@RequestBody @Validated(value={ValidGroupSave.class}) ChMenu menu, BindingResult bindingResult, 
			@PathVariable String roleIds) throws Exception{
		JSONObject json = new JSONObject();
		if(bindingResult.hasErrors()){
			json.put(SysConstants.Status.SUCCESS, false);
			json.put(SysConstants.Status.RESULT, bindingResult.getAllErrors().get(0).getDefaultMessage());
			log.debug(json.toString());
			return json;
		}
		if(chMenuService.saveOrUpdate(menu)>0){
			if(Assert.isValidString(menu.getMenuId())){
				chRoleMenuMapService.deleteByMenuId(menu.getMenuId());
			}
			if(Assert.isValidString(roleIds) && !SysConstants.Symbol.NEGATIVE_ONE.equals(roleIds)){
				String[] roleIdArray = roleIds.split(SysConstants.Symbol.COMMA);
				for(String roleId : roleIdArray){
					ChRole role = chRoleService.findByPrimaryKey(roleId);
					if(role!=null){
						ChRoleMenuMap roleMenuMap = new ChRoleMenuMap();
						roleMenuMap.setRoleId(roleId);
						roleMenuMap.setMenuId(menu.getMenuId());
						roleMenuMap.setRoleOrder(role.getRoleOrder());
						roleMenuMap.setMenuOrder(menu.getMenuOrder());
						chRoleMenuMapService.save(roleMenuMap);
					}
				}
			}
			json.put(SysConstants.MENU_ID, menu.getMenuId());
			json.put(SysConstants.Status.SUCCESS, true);
		}else{
			json.put(SysConstants.Status.SUCCESS, false);
			json.put(SysConstants.Status.RESULT, "未知错误");
		}
		log.debug(json.toString());
		return json;
	}
	
	/**
	 * 删除菜单信息
	 * @param ids
	 * @return
	 * @throws Exception 
	 */
	@RequestMapping(value="/delMenus/{ids}",method=RequestMethod.DELETE)
	@ResponseBody
	public Object delMenus(@PathVariable String ids) throws Exception{
		JSONObject json = new JSONObject();
		if(Assert.isValidString(ids)){
			String[] menuIds = ids.split(SysConstants.Symbol.COMMA);
			chMenuService.deleteByParentIdArray(menuIds);
			chMenuService.deleteByMenuIdArray(menuIds);
			chRoleMenuMapService.deleteByMenuIdArray(menuIds);
			json.put(SysConstants.Status.SUCCESS, true);
		}
		log.debug(ids+"  "+json.toString());
		return json;
	}
}
